package com.mach.platform.service;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import com.google.common.collect.Lists;
import com.mach.platform.domain.*;
import com.mach.platform.utils.BeanChangeUtil;
import com.mach.platform.utils.OrderDict;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.poi.ss.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 导出文件处理类
 */

@Service
public class ExportFileServiceImpl implements ExportFileService {

    //生产单
    @Autowired
    private ProductionOrderServiceImpl productionOrderService;
    @Autowired
    private ProductionOrderTermServiceImpl productionOrderTermService;

    //生产状态单
    @Autowired
    private ProductionStateServiceImpl productionStateService;

    //底布自主检查记录表
    @Autowired
    private UnderclothAutonomousInspectionRecordTableServiceImpl underclothAutonomous;

    //濕式產品卷取品質自主檢查記錄表
    @Autowired
    private CoilingQualityWetProductsServiceImpl coilingQualityWetProductsService;

    //DMF浓度记录表
    @Autowired
    private DMFConcentrationRecordServiceImpl dmfConcentrationRecordService;

    //投手自主检查记录表
    @Autowired
    private PitcherAutonomyServiceImpl pitcherAutonomyService;


    @Override
    public String hzFile(String time, String classBan, String type, HttpServletResponse response) {
        //判断是哪个报表
        judgeReportByType(time, classBan, type, response);
        return "操作成功";
    }

    /**
     * 获取 jar包所在 目录路径
     *
     * @return
     */
    public String getPicSavePath ( ) {
        ApplicationHome home = new ApplicationHome(getClass());
        File jarFile = home.getSource();
        return jarFile.getParentFile().getParentFile().getAbsolutePath();
    }

    private void judgeReportByType(String time, String classBan, String type, HttpServletResponse response) {

        switch(type){

            //生产单
            case "ProductionOrder" :
                productionOrderData(time, classBan, response);
                break;

            //生产状态单
            case "ProductionState" :
                productionStateData(time, response);
                break;

            //底布自主检查记录表
            case "UnderclothAutonomous" :
                underclothAutonomous(time, classBan, response);
                break;

            //湿式产品卷取品质自主检查记录表
            case "CoilingQualityWetProducts" :
                coilingQualityWetProducts(time, classBan, response);
                break;

            //DMF浓度记录表
            case "DMFConcentrationRecord" :
                dmfConcentrationRecord(time, response);
                break;

            //投手自主检查记录表
            case "PitcherAutonomy" :
                pitcherAutonomy(time, classBan, response);
                break;

            default:
                break;

        }
    }

    /**
     * 投手自主检查记录表
     * @param time
     * @param classBan
     * @param response
     */
    private void pitcherAutonomy(String time, String classBan, HttpServletResponse response) {
        List<PitcherAutonomy> pitcherAutonomies = this.pitcherAutonomyService.getProductionStateByTime(time, classBan);
        this.pitcherAutonomiesExport(time, pitcherAutonomies, response);
    }

    private void pitcherAutonomiesExport(String time, List<PitcherAutonomy> pitcherAutonomies, HttpServletResponse response) {

        if (!CollectionUtils.isNotEmpty(pitcherAutonomies)) {
            return;
        }

        //多sheep导出，18行一页
        List<List<PitcherAutonomy>> lists = Lists.partition(pitcherAutonomies, 12);

        Map<Integer, List<Map<String, Object>>> realMap = new HashMap<>();
        List<Map<String, Object>> mapList = null;
        for (int index = 0; index < lists.size(); index ++) {
            mapList = getPitcherAutonomyMap(lists.get(index));
            realMap.put(index, mapList);
        }

        TemplateExportParams params = new TemplateExportParams( getPicSavePath() + "/report/PitcherAutonomy.xls");
        String fileName = "投手自主检查记录表" + time + ".xls";
//        String fileName = "投手自主检查记录表" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + ".xls";

        Workbook workbook = ExcelExportUtil.exportExcelClone(realMap, params);
        downloadFile(response, workbook, fileName);
    }

    private List<Map<String, Object>> getPitcherAutonomyMap(List<PitcherAutonomy> pitcherAutonomies) {
        List<Map<String, Object>> result = Lists.newArrayList();
        Map<String, Object> map = new HashMap<String, Object>();

        List<Map<String, Object>> listMap = Lists.newArrayList();

        for (PitcherAutonomy pitcherAutonomy : pitcherAutonomies) {
            Map<String, Object> objectMap = BeanChangeUtil.beanToMap(pitcherAutonomy);
            listMap.add(objectMap);
        }

        //null赋值""
        listMap = listMapValueIsNullSetEmptyString(listMap);

        map.put("shiftSupervisor", getValue(pitcherAutonomies.get(0).getShiftSupervisor()));
        map.put("sectionChief", getValue(pitcherAutonomies.get(0).getSectionChief()));
        map.put("pitcher", getValue(pitcherAutonomies.get(0).getPitcher()));
        map.put("foreman", getValue(pitcherAutonomies.get(0).getForeman()));
        map.put("classBan", getValue(pitcherAutonomies.get(0).getClassBan()));

        map.put("listMap", listMap);
        result.add(map);
        return result;
    }

    /**
     * DMF浓度记录表
     * @param time
     * @param response
     */
    private void dmfConcentrationRecord(String time, HttpServletResponse response) {
        List<DMFConcentrationRecord> dmfConcentrationRecords = this.dmfConcentrationRecordService.getProductionStateByTime(time);
        this.dmfConcentrationRecordsExport(time, dmfConcentrationRecords, response);
    }

    private void dmfConcentrationRecordsExport(String time, List<DMFConcentrationRecord> dmfConcentrationRecords, HttpServletResponse response) {
        if (!CollectionUtils.isNotEmpty(dmfConcentrationRecords)) {
            return;
        }
        Map<String, Object> map = new HashMap<String, Object>();

        List<Map<String, Object>> listMap = Lists.newArrayList();

        for (DMFConcentrationRecord dmfConcentrationRecord : dmfConcentrationRecords) {
            Map<String, Object> objectMap = BeanChangeUtil.beanToMap(dmfConcentrationRecord);
            listMap.add(objectMap);
        }

        //null赋值""
        listMap = listMapValueIsNullSetEmptyString(listMap);

        map.put("shiftSupervisor", getValue(dmfConcentrationRecords.get(0).getShiftSupervisor()));
        map.put("sectionChief", getValue(dmfConcentrationRecords.get(0).getSectionChief()));

        map.put("listMap", listMap);

        TemplateExportParams params = new TemplateExportParams( getPicSavePath() + "/report/DMFConcentrationRecord.xls");
        String fileName = "DMF浓度记录表" + time + ".xls";

        Workbook workbook = ExcelExportUtil.exportExcel(params, map);
        downloadFile(response, workbook, fileName);
    }

    /**
     * 湿式产品卷取品质自主检查记录表
     * @param time
     * @param classBan
     * @param response
     */
    private void coilingQualityWetProducts(String time, String classBan, HttpServletResponse response) {
        List<CoilingQualityWetProducts> coilingQualityWetProducts = this.coilingQualityWetProductsService.getProductionStateByTime(time, classBan);
        this.coilingQualityWetProductsExport(time, coilingQualityWetProducts, response);
    }

    /**
     * 湿式产品卷取品质自主检查记录表r
     * @param time
     * @param coilingQualityWetProducts
     * @param response
     */
    private void coilingQualityWetProductsExport(String time, List<CoilingQualityWetProducts> coilingQualityWetProducts, HttpServletResponse response) {
        if (!CollectionUtils.isNotEmpty(coilingQualityWetProducts)) {
            return;
        }


        //多sheep导出，18行一页
        List<List<CoilingQualityWetProducts>> lists = Lists.partition(coilingQualityWetProducts, 15);

        Map<Integer, List<Map<String, Object>>> realMap = new HashMap<>();
        List<Map<String, Object>> mapList = null;
        for (int index = 0; index < lists.size(); index ++) {
            mapList = getCoilingQualityMap(lists.get(index));
            realMap.put(index, mapList);
        }



        TemplateExportParams params = new TemplateExportParams( getPicSavePath() + "/report/CoilingQualityWetProducts.xls");
        String fileName = "濕式產品卷取品質自主檢查記錄表" + time
                + coilingQualityWetProducts.get(0).getClassBan() + ".xls";

        Workbook workbook = ExcelExportUtil.exportExcelClone(realMap, params);
        downloadFile(response, workbook, fileName);
    }

    private List<Map<String, Object>> getCoilingQualityMap(List<CoilingQualityWetProducts> coilingQualityWetProducts) {
        List<Map<String, Object>> result = Lists.newArrayList();
        Map<String, Object> map = new HashMap<String, Object>();

        List<Map<String, Object>> listMap = Lists.newArrayList();

        for (CoilingQualityWetProducts coilingQualityWetProduct : coilingQualityWetProducts) {
            Map<String, Object> objectMap = BeanChangeUtil.beanToMap(coilingQualityWetProduct);
            listMap.add(objectMap);
        }

        //null赋值""
        listMap = listMapValueIsNullSetEmptyString(listMap);

        map.put("classBan", getValue(coilingQualityWetProducts.get(0).getClassBan()));
        map.put("sectionChief", getValue(coilingQualityWetProducts.get(0).getSectionChief()));
        map.put("shiftSupervisor", getValue(coilingQualityWetProducts.get(0).getShiftSupervisor()));
        map.put("foreman", getValue(coilingQualityWetProducts.get(0).getForeman()));
        map.put("procurator", getValue(coilingQualityWetProducts.get(0).getProcurator()));

        map.put("listMap", listMap);
        result.add(map);
        return result;
    }

    private String getValue(String value) {
        return value == null ? "" : value;
    }

    /**
     * 底布自主检查记录表数据
     * @param time
     * @param classBan
     * @param response
     */
    private void underclothAutonomous(String time, String classBan, HttpServletResponse response) {
        List<UnderclothAutonomousInspectionRecordTable> underclothAutonomous = this.underclothAutonomous.getProductionStateByTime(time, classBan);
        this.underclothAutonomousExport(time, underclothAutonomous, response);
    }

    private void underclothAutonomousExport(String time, List<UnderclothAutonomousInspectionRecordTable> underclothAutonomous, HttpServletResponse response) {
        if (!CollectionUtils.isNotEmpty(underclothAutonomous)) {
            return;
        }

        //多sheep导出，13行一页
        List<List<UnderclothAutonomousInspectionRecordTable>> lists = Lists.partition(underclothAutonomous, 13);

        Map<Integer, List<Map<String, Object>>> realMap = new HashMap<>();
        List<Map<String, Object>> mapList = null;
        for (int index = 0; index < lists.size(); index ++) {
            mapList = getStringObjectMap(lists.get(index));
            realMap.put(index, mapList);
        }




        TemplateExportParams params = new TemplateExportParams( getPicSavePath() + "/report/UnderclothAutonomous.xls");
        String fileName = "底布自主检查记录表数据" + time
                + underclothAutonomous.get(0).getClassBan() + ".xls";

        Workbook workbook = ExcelExportUtil.exportExcelClone(realMap, params);
        downloadFile(response, workbook, fileName);
    }

    private List<Map<String, Object>> getStringObjectMap(List<UnderclothAutonomousInspectionRecordTable> underclothAutonomous) {
        List<Map<String, Object>> result = Lists.newArrayList();
        Map<String, Object> map = new HashMap<String, Object>();

        List<Map<String, Object>> listMap = Lists.newArrayList();

        for (UnderclothAutonomousInspectionRecordTable underclothAutonomou : underclothAutonomous) {
            Map<String, Object> objectMap = BeanChangeUtil.beanToMap(underclothAutonomou);
            listMap.add(objectMap);
        }

        //null赋值""
        listMap = listMapValueIsNullSetEmptyString(listMap);

        map.put("classBan", getValue(underclothAutonomous.get(0).getClassBan()));
        map.put("sectionChief", getValue(underclothAutonomous.get(0).getSectionChief()));
        map.put("shiftSupervisor", getValue(underclothAutonomous.get(0).getShiftSupervisor()));
        map.put("foreman", getValue(underclothAutonomous.get(0).getForeman()));

        map.put("listMap", listMap);
        result.add(map);
        return result;
    }

    /**
     * 生产状态单数据
     * @param time
     * @param response
     */
    private void productionStateData(String time, HttpServletResponse response) {
        List<ProductionState> productionStates =  this.productionStateService.getProductionStateByTime(time);
        this.productionStateExport(time, productionStates, response);
    }

    /**
     * 生产单数据
     * @param time
     * @param classBan
     * @param response
     */
    private void productionOrderData(String time, String classBan, HttpServletResponse response) {
        List<ProductionOrder> productionOrders = this.productionOrderService.getProductionOrder(time, classBan);
        List<Long> productionOrderIds = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(productionOrders)){
            productionOrders.forEach(item -> productionOrderIds.add(item.getId()));
        }
        List<ProductionOrderTerm> productionOrderTerms = this.productionOrderTermService.getListByProductionOrdersIds(productionOrderIds);
        this.productionOrderTermExport(time, productionOrders, productionOrderTerms, response);
    }

    /**
     * 生产单报表
     * @param time
     * @param productionOrders
     * @param productionOrderTerms
     * @param response
     */
    private void productionOrderTermExport(String time, List<ProductionOrder> productionOrders, List<ProductionOrderTerm> productionOrderTerms, HttpServletResponse response) {
        if (!CollectionUtils.isNotEmpty(productionOrderTerms) && !CollectionUtils.isNotEmpty(productionOrders)) {
            return;
        }

        //多sheep导出，18行一页
        List<List<ProductionOrderTerm>> lists = Lists.partition(productionOrderTerms, 18);

        Map<Integer, List<Map<String, Object>>> realMap = new HashMap<>();
        List<Map<String, Object>> mapList = null;
        for (int index = 0; index < lists.size(); index ++) {
            mapList = getStringObjectMap(productionOrders, lists.get(index));
            realMap.put(index, mapList);
        }

        TemplateExportParams params = new TemplateExportParams( getPicSavePath() + "/report/ProductionOrder.xls", true);
        String fileName = "生產單" + time + productionOrders.get(0).getClassBan() + ".xls";

        Workbook workbook = ExcelExportUtil.exportExcelClone(realMap, params);
        downloadFile(response, workbook, fileName);
    }

    private List<Map<String, Object>> getStringObjectMap(List<ProductionOrder> productionOrders, List<ProductionOrderTerm> productionOrderTerms) {
        List<Map<String, Object>> mapList = Lists.newArrayList();

        Map<String, Object> map = new HashMap<String, Object>();

        List<Map<String, Object>> productionOrderTermsListMap = Lists.newArrayList();
        List<Map<String, Object>> productionOrdersListMap = Lists.newArrayList();

        for (ProductionOrder productionOrder : productionOrders) {
            Map<String, Object> objectMap = BeanChangeUtil.beanToMap(productionOrder);
            productionOrdersListMap.add(objectMap);
        }

        for (ProductionOrderTerm productionOrderTerm : productionOrderTerms) {
            Map<String, Object> objectMap = BeanChangeUtil.beanToMap(productionOrderTerm);
            productionOrderTermsListMap.add(objectMap);
        }

        //null赋值""
        productionOrderTermsListMap = listMapValueIsNullSetEmptyString(productionOrderTermsListMap);

        //null赋值""
        productionOrdersListMap = listMapValueIsNullSetEmptyString(productionOrdersListMap);

        map.put("classBan", getValue(productionOrders.get(0).getClassBan()));
        map.put("sectionChief", getValue(productionOrders.get(0).getSectionChief()));
        map.put("shiftSupervisor", getValue(productionOrders.get(0).getShiftSupervisor()));

        map.put("listMap", productionOrderTermsListMap);
        map.put("list", productionOrdersListMap);
        mapList.add(map);
        return mapList;
    }

    private List<Map<String, Object>> listMapValueIsNullSetEmptyString(List<Map<String, Object>> listMap) {
        if (CollectionUtils.isNotEmpty(listMap)){
            return listMap;
        }

        for (Map<String, Object> objectMap : listMap) {
            for (Map.Entry<String, Object> objectEntry : objectMap.entrySet()) {
                if (objectEntry.getValue() == null) {
                    objectEntry.setValue("");
                }
            }
        }
        return listMap;
    }

    /**
     * 生产状态单报表
     * @param time
     * @param data
     * @param response
     */
    private void productionStateExport(String time, List<ProductionState> data, HttpServletResponse response) {
        if (!CollectionUtils.isNotEmpty(data)) {
            return;
        }
        //处理数据
        Map<String, List<ProductionState>> resultList = data.stream().collect(Collectors.groupingBy(ProductionState::getClassBan));

        Map<String, Object> map = new HashMap<String, Object>();

        List<ProductionState> productionStateNight = null;
        List<ProductionState> productionStateMorning = null;
        List<ProductionState> productionStateNoon = null;
        for (Map.Entry<String, List<ProductionState>> entry : resultList.entrySet()){
            if (OrderDict.NIGHT1.equals(entry.getKey())){
                map.put("productNameRateNight", entry.getValue().get(0).getProductNameRate());//定制号码
                map.put("abnormalDescriptionNight", entry.getValue().get(0).getAbnormalDescription());//异常说明
                map.put("processObjectsForemanNight", entry.getValue().get(0).getProcessObjectsForeman());//领班
                map.put("processObjectsOperatorNight", entry.getValue().get(0).getProcessObjectsOperator());//操作员
                productionStateNight = entry.getValue();
            }
            if (OrderDict.MORNING.equals(entry.getKey())){
                map.put("productNameRateMorning", entry.getValue().get(0).getProductNameRate());//定制号码
                map.put("abnormalDescriptionMorning", entry.getValue().get(0).getAbnormalDescription());//异常说明
                map.put("processObjectsForemanMorning", entry.getValue().get(0).getProcessObjectsForeman());//领班
                map.put("processObjectsOperatorMorning", entry.getValue().get(0).getProcessObjectsOperator());//操作员
                productionStateMorning = entry.getValue();
            }
            if (OrderDict.NOON.equals(entry.getKey())){
                map.put("productNameRateNoon", entry.getValue().get(0).getProductNameRate());//定制号码
                map.put("abnormalDescriptionNoon", entry.getValue().get(0).getAbnormalDescription());//异常说明
                map.put("processObjectsForemanNoon", entry.getValue().get(0).getProcessObjectsForeman());//领班
                map.put("processObjectsOperatorNoon", entry.getValue().get(0).getProcessObjectsOperator());//操作员
                productionStateNoon = entry.getValue();
            }
        }

        TemplateExportParams params = new TemplateExportParams( getPicSavePath() + "/report/ProductionState.xls");

        List<Map<String, String>> listNight = this.getListMapData(productionStateNight);

        List<Map<String, String>> listMorning = this.getListMapData(productionStateMorning);

        List<Map<String, String>> listNoon = this.getListMapData(productionStateNoon);
        map.put("listNight", listNight);
        map.put("listMorning", listMorning);
        map.put("listNoon", listNoon);

//        yyyy-MM-dd HH:mm:ss
//        String savePath = getPicSavePath() + "/productionState/";
        String fileName = "生產狀態單" + time + ".xls";

        Workbook workbook = ExcelExportUtil.exportExcel(params, map);

        CellStyle style = workbook.getCellStyleAt(1);
        setWorkBookStyle(style);

        downloadFile(response, workbook, fileName);

    }

    private CellStyle setWorkBookStyle(CellStyle style) {
        //下边框
        style.setBorderBottom(BorderStyle.THIN);
        //左边框
        style.setBorderLeft(BorderStyle.THIN);
        //上边框
        style.setBorderTop(BorderStyle.THIN);
        //右边框
        style.setBorderRight(BorderStyle.THIN);
        //水平居中
        style.setAlignment(HorizontalAlignment.CENTER);
        //上下居中
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        //设置自动换行
        style.setWrapText(true);
        return style;
    }

    /**
     * 获取生产状态单的项
     * @param productionStates
     * @return
     */
    private List<Map<String, String>> getListMapData(List<ProductionState> productionStates) {
        List<Map<String, String>> result = Lists.newArrayList();

        if (!CollectionUtils.isNotEmpty(productionStates)){
            return result;
        }
        productionStates.forEach(productionState -> {
            Map<String, String> lm = new HashMap<String, String>();

            String formatTime = this.getFormatTime(productionState.getProductionStateTime());
            lm.put("time", formatTime);
            lm.put("productionStateCode", productionState.getProductionStateCode());
            lm.put("productionStateActual", productionState.getProductionStateActual());
            lm.put("productionStateStandard", productionState.getProductionStateStandard());

            result.add(lm);
        });
        return result;
    }

    /**
     * 格式化时间到小时 16:00
     * @param productionStateTime
     * @return
     */
    private String getFormatTime(LocalDateTime productionStateTime) {
        if (ObjectUtils.allNotNull(productionStateTime)){
            return productionStateTime.format(DateTimeFormatter.ofPattern("HH:mm"));
        }
        return null;
    }

    /**
     * 导出后下载文件
     * @param response resp
     * @param workbook
     * @param fileName
     */
    public void downloadFile(HttpServletResponse response, Workbook workbook, String fileName) {
        try {
            response.setHeader("Content-Disposition",
                    "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
            response.setContentType("application/vnd.ms-excel; charset=UTF-8");

            OutputStream outputStream = response.getOutputStream();
            workbook.write(outputStream);

            outputStream.close();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
